home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-08-14 | 55.9 KB | 2,016 lines |
- Newsgroups: comp.sources.amiga
- Path: abcfd20.larc.nasa.gov!amiga-request
- From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v90i221: SetCPU 1.60 - identify and adjust parameters based on cpu type, Part01/04
- Message-ID: <comp.sources.amiga:v90i221@abcfd20.larc.nasa.gov>
- Sender: tadguy@abcfd20.larc.nasa.gov (Tad Guy)
- Reply-To: daveh@cbmvax.commodore.com (Dave Haynie)
- X-Post-Discussions-To: comp.sys.amiga
- Organization: NASA Langley Research Center, Hampton, VA USA
- Date: 14 Aug 90 21:35:39 GMT
- Approved: tadguy@abcfd01.larc.nasa.gov (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
-
- Submitted-by: daveh@cbmvax.commodore.com (Dave Haynie)
- Posting-number: Volume 90, Issue 221
- Archive-name: util/setcpu-1.60/part01
-
- [ uuencoded executable enclosed ...tad ]
-
- Here's the latest SetCPU program. This archive contains the executable,
- docs, and source files. This program is used to identify the CPU/FPU/MMU
- combinations in an Amiga computer, make decisions based on this, modify
- cache parameters, and on MMU-Based machines, run ROM emulations. The ROM
- emulation mechanism now supports 512K ROMs such as those used for AmigaOS 2.0.
- This program and the sources are public domain.
-
- -Dave Haynie
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 4)."
- # Contents: CardROMList control.a control.i diskio.c expdev.c idents.a
- # makefile misc.c other.a reboot.a setcpu.i
- # Wrapped by tadguy@abcfd20 on Tue Aug 14 17:35:34 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'CardROMList' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CardROMList'\"
- else
- echo shar: Extracting \"'CardROMList'\" \(59 characters\)
- sed "s/^X//" >'CardROMList' <<'END_OF_FILE'
- X0x202 0x01 0x10000 0x8000 0x4000 CBM_2090A_Disk_Controller
- END_OF_FILE
- if test 59 -ne `wc -c <'CardROMList'`; then
- echo shar: \"'CardROMList'\" unpacked with wrong size!
- fi
- # end of 'CardROMList'
- fi
- if test -f 'control.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'control.a'\"
- else
- echo shar: Extracting \"'control.a'\" \(5731 characters\)
- sed "s/^X//" >'control.a' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; CONTROL.A MODULE
- X;
- X; This module contains functions that access various control
- X; registers in the 32 bit CPUs and MMUs.
- X;
- X;======================================================================
- X
- X include "setcpu.i"
- X
- X cseg
- X
- X;**********************************************************************
- X;
- X; These functions work with the CPU control registers.
- X;
- X**********************************************************************
- X
- X xdef _SetCACR ; Set CACR register
- X xdef _GetCACR ; Get CACR register
- X xdef _GetVBR ; Get the Vector Base Register
- X
- X;======================================================================
- X;
- X; This function sets the value of the 68020/68030 CACR register.
- X; It assumes a 68020 or 68030 based system.
- X;
- X; void SetCACR(cacr)
- X; ULONG cacr;
- X;
- X;======================================================================
- X
- X_SetCACR:
- X move.l 4(sp),d0 ; New CACR is on stack
- X move.l 4,a6 ; Get ExecBase
- X
- X move.w LIB_VERSION(a6),d1 ; Are we in 2.0?
- X cmp.w #36,d1 ; If so, use the 2.0 function
- X blt MySetCACR
- X
- X move.l #$ffffffff,d1
- X CALLSYS CacheControl
- X rts
- X
- XMySetCACR:
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give it back
- X rts
- X1$
- X MOVEC_ d0,cacr ; Set the CACR
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the 68020/68030 CACR register. It assumes
- X; a 68020 or better system.
- X;
- X; ULONG GetCACR()
- X;
- X;======================================================================
- X
- X_GetCACR:
- X move.l 4,a6 ; Get ExecBase
- X
- X move.w LIB_VERSION(a6),d1 ; Are we in 2.0?
- X cmp.w #36,d1 ; If so, use the 2.0 function
- X blt MyGetCACR
- X
- X moveq.l #0,d0
- X move.l d0,d1
- X CALLSYS CacheControl
- X rts
- X
- XMyGetCACR:
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give back register
- X rts
- X1$
- X MOVEC_ cacr,d0 ; Make CACR the return value
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the value of the Vector Base Register;
- X; all exceptions are referenced from this. This function assumes
- X; we're on a CPU with a VBR (eg, no 68000's need apply).
- X;
- X; ULONG *GetVBR()
- X;
- X;======================================================================
- X
- X_GetVBR:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give back register
- X rts
- X1$
- X MOVEC_ vbr,d0 ; Make CACR the return value
- X rte
- X
- X;**********************************************************************
- X;
- X; These functions access MMU registers
- X;
- X;**********************************************************************
- X
- X xdef _GetCRP ; Gets MMU CRP register
- X xdef _SetCRP ; Sets MMU CRP register
- X xdef _GetTC ; Gets MMU TC register
- X xdef _SetTC ; Gets MMU TC register
- X
- X;======================================================================
- X;
- X; This function returns the MMU CRP register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone). Note that the
- X; CRP register is two longwords long.
- X;
- X; void GetCRP(ULONG *)
- X;
- X;======================================================================
- X
- X_GetCRP:
- X move.l 4(sp),a0 ; Pointer to the CRP storage area
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 2$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5
- X rts
- X2$
- X PMOVE_ crp,(a0) ; Just get the CRP register
- X rte
- X
- X;======================================================================
- X;
- X; This function sets the MMU CRP register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone). Note that the
- X; CRP register is two longwords long.
- X;
- X; void SetCRP(ULONG *)
- X;
- X;======================================================================
- X
- X_SetCRP:
- X move.l 4(sp),a0 ; Pointer to the CRP storage area
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X movem.l (sp)+,a5 ; Give back registers
- X rts
- X1$
- X PMOVE_ (a0),crp ; Just load the CRP register
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the MMU TC register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone).
- X;
- X; ULONG GetTC()
- X;
- X;======================================================================
- X
- X_GetTC:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X subq.l #4,sp ; Make a place to dump TC
- X move.l sp,a0
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp),d0 ; Here's the result
- X addq.l #4,sp
- X move.l (sp)+,a5
- X rts
- X1$
- X PMOVE_ tc,(a0) ; Just get the TC register
- X rte
- X
- X;======================================================================
- X;
- X; This function sets the MMU TC register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone).
- X;
- X; void SetTC(ULONG)
- X;
- X;======================================================================
- X
- X_SetTC:
- X lea.l 4(sp),a0 ; Get address of our new TC value
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5
- X rts
- X1$
- X PMOVE_ (a0),tc ; Just set the TC register
- X rte
- X
- X end
- END_OF_FILE
- if test 5731 -ne `wc -c <'control.a'`; then
- echo shar: \"'control.a'\" unpacked with wrong size!
- fi
- # end of 'control.a'
- fi
- if test -f 'control.i' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'control.i'\"
- else
- echo shar: Extracting \"'control.i'\" \(5383 characters\)
- sed "s/^X//" >'control.i' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; CONTROL.A MODULE
- X;
- X; This module contains functions that access various control
- X; registers in the 32 bit CPUs and MMUs.
- X;
- X;======================================================================
- X
- X include "setcpu.i"
- X
- X cseg
- X
- X;**********************************************************************
- X;
- X; These functions work with the CPU control registers.
- X;
- X**********************************************************************
- X
- X xdef _SetCACR ; Set CACR register
- X xdef _GetCACR ; Get CACR register
- X xdef _GetVBR ; Get the Vector Base Register
- X
- X;======================================================================
- X;
- X; This function sets the value of the 68020/68030 CACR register.
- X; It assumes a 68020 or 68030 based system.
- X;
- X; void SetCACR(cacr)
- X; ULONG cacr;
- X;
- X;======================================================================
- X
- X_SetCACR:
- X move.l 4(sp),d0 ; New CACR is on stack
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give it back
- X rts
- X1$
- X MOVEC_ d0,cacr ; Set the CACR
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the 68020/68030 CACR register. It assumes
- X; a 68020 or better system.
- X;
- X; ULONG GetCACR()
- X;
- X;======================================================================
- X
- X_GetCACR:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give back register
- X rts
- X1$
- X MOVEC_ cacr,d0 ; Make CACR the return value
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the value of the Vector Base Register;
- X; all exceptions are referenced from this. This function assumes
- X; we're on a CPU with a VBR (eg, no 68000's need apply).
- X;
- X; ULONG *GetVBR()
- X;
- X;======================================================================
- X
- X_GetVBR:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp) ; Save this register
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give back register
- X rts
- X1$
- X MOVEC_ vbr,d0 ; Make CACR the return value
- X rte
- X
- X;**********************************************************************
- X;
- X; These functions access MMU registers
- X;
- X;**********************************************************************
- X
- X xdef _GetCRP ; Gets MMU CRP register
- X xdef _SetCRP ; Sets MMU CRP register
- X xdef _GetTC ; Gets MMU TC register
- X xdef _SetTC ; Gets MMU TC register
- X
- X;======================================================================
- X;
- X; This function returns the MMU CRP register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone). Note that the
- X; CRP register is two longwords long.
- X;
- X; void GetCRP(ULONG *)
- X;
- X;======================================================================
- X
- X_GetCRP:
- X move.l 4(sp),a0 ; Pointer to the CRP storage area
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 2$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5
- X rts
- X2$
- X PMOVE_ crp,(a0) ; Just get the CRP register
- X rte
- X
- X;======================================================================
- X;
- X; This function sets the MMU CRP register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone). Note that the
- X; CRP register is two longwords long.
- X;
- X; void SetCRP(ULONG *)
- X;
- X;======================================================================
- X
- X_SetCRP:
- X move.l 4(sp),a0 ; Pointer to the CRP storage area
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X movem.l (sp)+,a5 ; Give back registers
- X rts
- X1$
- X PMOVE_ (a0),crp ; Just load the CRP register
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the MMU TC register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone).
- X;
- X; ULONG GetTC()
- X;
- X;======================================================================
- X
- X_GetTC:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X subq.l #4,sp ; Make a place to dump TC
- X move.l sp,a0
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp),d0 ; Here's the result
- X addq.l #4,sp
- X move.l (sp)+,a5
- X rts
- X1$
- X PMOVE_ tc,(a0) ; Just get the TC register
- X rte
- X
- X;======================================================================
- X;
- X; This function sets the MMU TC register. It assumes a 68020
- X; system with MMU, or a 68030 based system (eg, test for MMU before
- X; you call this, or you wind up in The Guru Zone).
- X;
- X; void SetTC(ULONG)
- X;
- X;======================================================================
- X
- X_SetTC:
- X lea.l 4(sp),a0 ; Get address of our new TC value
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5
- X rts
- X1$
- X PMOVE_ (a0),tc ; Just set the TC register
- X rte
- X
- END_OF_FILE
- if test 5383 -ne `wc -c <'control.i'`; then
- echo shar: \"'control.i'\" unpacked with wrong size!
- fi
- # end of 'control.i'
- fi
- if test -f 'diskio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'diskio.c'\"
- else
- echo shar: Extracting \"'diskio.c'\" \(5075 characters\)
- sed "s/^X//" >'diskio.c' <<'END_OF_FILE'
- X/*
- X SetCPU V1.60
- X by Dave Haynie, April 13, 1990
- X Released to the Public Domain
- X
- X DISKIO.C MODULE
- X
- X This module is responsible for fetching ROM images from various
- X kinds of disks and files.
- X*/
- X
- X#include "setcpu.h"
- X
- X/* This function allocates a ROM image from a KickStart disk for KICKROM. */
- X
- X#define ColorShift(x) (LONG)((((x)&0xf)+1)%15)
- X
- Xstruct systag *AllocKSImage(name)
- Xchar *name;
- X{
- X struct systag *tag = NULL;
- X ULONG *buf = NULL, blocks;
- X char *ptr;
- X LONG unit, i, r = 0x0004L, g = 0x0008L, b = 0x000cL,start;
- X struct MsgPort *port = NULL;
- X struct IOStdReq *req = NULL;
- X struct Window *hand = NULL;
- X BOOL devok = FALSE;
- X
- X /* Then we expect it to be a kickstart disk, so we check out the device,
- X the disk, etc. If all goes well, we'll be in business. */
- X
- X if ((unit = CheckTDDev(name)) == -1L) {
- X LoadErr = 16;
- X goto fail;
- X }
- X
- X /* This is the stuff that need opening... */
- X port = (struct MsgPort *) CreatePort("diskreq.port",0L);
- X if (port) req = CreateStdIO(port,0L);
- X if (req) devok = !OpenDevice("trackdisk.device",unit,(struct IORequest *)req,0L);
- X if (devok) buf = (ULONG *)AllocMem(512L,MEMF_CHIP);
- X if (!port || !req || !devok || !buf) goto fail;
- X
- X /* Make sure we're a kick disk. */
- X hand = CoolHand();
- X while ((ReadBuf((char *)buf,0L,req) != READOK) ||
- X !strniequ("KICK",(char *)buf,4))
- X Delay(150L);
- X
- X /* Check the size of this kickstart. */
- X
- X if (!(tag = AllocMem(SizeOf(struct systag),0L))) goto fail;
- X start = 0;
- X do {
- X if (ReadBuf((char *)buf,++start,req) != READOK) goto fail;
- X ptr = (char *)SizeROM(tag,buf,TRUE);
- X } while (ptr == NULL && start < 32L);
- X
- X if (!ptr) goto fail;
- X
- X blocks = tag->romsize/512L;
- X
- X /* Looks like we're in shape to get the actual system. */
- X
- X SetRGB4(&(hand->WScreen->ViewPort),2L,r,g,b);
- X for (i = 1; i <= blocks; ++i) {
- X if (ReadBuf((char *)buf,i,req) != READOK) break;
- X MemCopy((char *)buf,ptr,512L);
- X ptr += 512L;
- X r = ColorShift(r);
- X g = ColorShift(g);
- X b = ColorShift(b);
- X
- X SetRGB4(&(hand->WScreen->ViewPort),2L,r,g,b);
- X }
- X LoadErr = 0;
- X
- Xdone:
- X if (buf) FreeMem((char *)buf,512L);
- X if (devok) {
- X MotorOff(req);
- X CloseDevice((struct IORequest *)req);
- X }
- X if (req) DeleteStdIO(req);
- X if (port) DeletePort(port);
- X return tag;
- X
- Xfail:
- X if (tag) {
- X FreeMem(tag,SizeOf(struct systag));
- X tag = NULL;
- X }
- X goto done;
- X}
- X
- X/* This function allocates a ROM image from an AmigaDOS file for either
- X KICKROM or FASTROM. */
- X
- Xstruct systag *AllocFILEImage(name)
- Xchar *name;
- X{
- X struct systag *tag = NULL;
- X ULONG *rom = NULL, space[2], check;
- X BPTR file = NULL;
- X struct FileInfoBlock *fib;
- X
- X /* First off, let's check out this here file. */
- X
- X if (!(fib = AllocMem(SizeOf(struct FileInfoBlock),0L))) goto fail;
- X if (!(file = Lock(name,ACCESS_READ))) {
- X LoadErr = 24;
- X goto fail;
- X }
- X Examine(file,fib);
- X UnLock(file);
- X file = NULL;
- X if (fib->fib_DirEntryType > 0L || !(file = Open(name,MODE_OLDFILE))) {
- X LoadErr = 24;
- X goto fail;
- X }
- X
- X /* Try to find a sensible ROM header, either its a plain ROM, or the one
- X with the extra sizing info at the head. */
- X
- X Read(file,(char *)space,8L);
- X if (space[0])
- X Seek(file,0L,OFFSET_BEGINNING);
- X else {
- X check = space[1];
- X Read(file,(char *)space,8L);
- X Seek(file,8L,OFFSET_BEGINNING);
- X }
- X
- X /* Let's allocate the space I need. KICKROMs don't use a disk image
- X directly, so they don't need an MMU table and don't care about any special
- X alignment. FASTROMs read from disk do care, so I will align this image. */
- X
- X SmartlyGetRange();
- X if (!(tag = AllocAligned(SizeOf(struct systag),8L))) goto fail;
- X
- X if (!(rom = SizeROM(tag,space,TRUE))) {
- X LoadErr == 22;
- X goto fail;
- X }
- X if (tag->romsize != Read(file,(char *)rom,tag->romsize)) {
- X LoadErr = 23;
- X goto fail;
- X }
- X Close(file);
- X FreeMem(fib,SizeOf(struct FileInfoBlock));
- X return tag;
- X
- Xfail:
- X if (file) Close(file);
- X if (fib) FreeMem(fib,SizeOf(struct FileInfoBlock));
- X if (rom) FreeMem(rom,tag->romsize);
- X if (tag) FreeMem(tag,SizeOf(struct systag));
- X return NULL;
- X}
- X
- X/* This function gets a ROM image from disk; in temporary unaligned memory
- X for a KICKROM image, permanent aligned memory for a FASTROM image. */
- X
- Xstruct systag *AllocDISKImage(type,name)
- XUWORD type;
- Xchar *name;
- X{
- X struct systag *tag;
- X ULONG *table;
- X
- X /* Reset the error code. */
- X LoadErr = 0;
- X
- X /* Let's check out this here file. It's easy to tell; we want a FILE
- X image if we aren't passed a KICK_ROM request with a device name. */
- X
- X if (type == ROM_FAST || name[strlen(name)-1] != ':') {
- X tag = AllocFILEImage(name);
- X if ((tag->romtype = type) == ROM_FAST) {
- X FindWrap(tag);
- X if (!(table = AllocAligned(tag->tablesize+4,TABROUND))) return NULL;
- X tag->maintable = table;
- X FillBasicTable(tag,FALSE);
- X }
- X return tag;
- X }
- X
- X return AllocKSImage(name);
- X}
- END_OF_FILE
- if test 5075 -ne `wc -c <'diskio.c'`; then
- echo shar: \"'diskio.c'\" unpacked with wrong size!
- fi
- # end of 'diskio.c'
- fi
- if test -f 'expdev.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expdev.c'\"
- else
- echo shar: Extracting \"'expdev.c'\" \(6166 characters\)
- sed "s/^X//" >'expdev.c' <<'END_OF_FILE'
- X/*
- X SetCPU V1.60
- X by Dave Haynie, April 13, 1990
- X Released to the Public Domain
- X
- X EXPANSION DEVICE MODULE
- X
- X This module maintains the code used to detect and translate
- X a given expansion device.
- X*/
- X
- X#include "setcpu.h"
- X
- X/* ====================================================================== */
- X
- X/* Stuff I need for this module. */
- X
- Xchar *malloc();
- Xint sscanf();
- X
- X/* ====================================================================== */
- X
- X/* This section manages devices with on-board ROM. The actual
- X implementation of this stuff is pretty well hidden in this
- X module. */
- X
- X/* This structure manages the expansion devices that we know about. */
- X
- Xstruct ExpDev {
- X struct Node node;
- X ULONG manuf;
- X ULONG board;
- X ULONG size;
- X ULONG romoffset;
- X ULONG romsize;
- X};
- X
- X/* Here's the list of all the devices we know about. */
- X
- Xstatic struct List Devices =
- X {(struct Node *)&Devices.lh_Tail,NULL,(struct Node *)&Devices.lh_Head,0,0};
- X
- Xstatic struct ExpDev *CurrentDevice = NULL;
- X
- X/* This function reads the list of expansion devices from the given file.
- X The file should contain data for one device per line, with the
- X following format:
- X
- X MANUF PROD SIZE START LENGTH id-string
- X
- X Except for the last field, all numbers are integers, which may be
- X expressed as decimal or hexidecimal. The last field is a text
- X string which may contain any information. It's very likely that
- X the line for each device will have to be supplied by the maker
- X of any device, since there's no way to figure out if a device's
- X ROM is on the same MMU page as an important I/O register which
- X shouldn't ever be translated. The description I use for the Amiga
- X 2090A controller is:
- X
- X 0x202 0x01 0x10000 0x8000 0x4000 CBM 2090A Disk Controller
- X
- X The actual fields are:
- X
- X MANUF The Manufacturer's code for the PIC
- X PROD The Product code for the PIC
- X SIZE The configured size of the PIC
- X START The offset from the PIC base for the start of ROM
- X LENGTH The length of the ROM
- X id-string Whatever the hell you want
- X*/
- X
- XLONG ReadExpDevs(name)
- Xchar *name;
- X{
- X FILE *file;
- X char buf[256],msg[256];
- X struct ExpDev *ed;
- X int len,i;
- X
- X if (!(file = fopen(name,"r"))) return FALSE;
- X
- X while (fgets(buf,256,file)) {
- X ed = (struct ExpDev *)malloc(sizeof(struct ExpDev));
- X if (sscanf(buf,"%lx%lx%lx%lx%lx%s",&ed->manuf,&ed->board,&ed->size,
- X &ed->romoffset,&ed->romsize,msg) >= 5) {
- X if (len = strlen(msg)) {
- X ed->node.ln_Name = (char *)malloc(len+1);
- X for (i = 0; i <= len; ++i)
- X ed->node.ln_Name[i] = (msg[i] == '_')?' ':msg[i];
- X }
- X if (ed->romsize = ((ed->romsize/DEVROUND)*DEVROUND))
- X AddHead(&Devices,(struct Node *)ed);
- X else
- X free(ed);
- X } else
- X free(ed);
- X }
- X fclose(file);
- X CurrentDevice = (struct ExpDev *)Devices.lh_Head;
- X return TRUE;
- X}
- X
- X/* ====================================================================== */
- X
- X/* This function returns the ROM information I'll need for a given
- X expansion device. Because of some Commodore screwups, the A2090A
- X appears the same device as other boards like the Commodore RAM
- X board. So I have the size passed as well, as a consistency
- X check. The returned ExpROMData structure is allocated here, and
- X can be freed when no longer needed. */
- X
- Xstruct ExpROMData *GetExpROM()
- X{
- X struct ConfigDev *cd;
- X struct DiagArea *da;
- X struct ExpROMData *ed;
- X
- X if (!CurrentDevice || !ExpansionBase) return NULL;
- X cd = FindConfigDev(NULL,CurrentDevice->manuf,CurrentDevice->board);
- X
- X while (cd) {
- X if (((ULONG)cd->cd_BoardSize == CurrentDevice->size) &&
- X (cd->cd_Rom.er_Type & ERTF_DIAGVALID)) {
- X da = (struct DiagArea *)(((ULONG)cd->cd_BoardAddr)+((ULONG)cd->cd_Rom.er_InitDiagVec));
- X
- X /* This is just a sanity check to make sure we really use the
- X ROM out on this card -- a nybble or byte wide ROM will be in
- X RAM already. */
- X if ((da->da_Config & DAC_BUSWIDTH) == DAC_WORDWIDE) {
- X ed = (struct ExpROMData *)AllocMem(SizeOf(struct ExpROMData),MEMF_CLEAR);
- X ed->ROMbase = ((ULONG)cd->cd_BoardAddr) + CurrentDevice->romoffset;
- X ed->ROMsize = CurrentDevice->romsize;
- X ed->imagebase = NULL;
- X ed->tablebase = NULL;
- X ed->name = (char *)AllocMem((ULONG)
- X strlen(CurrentDevice->node.ln_Name)+1,0L);
- X strcpy(ed->name,CurrentDevice->node.ln_Name);
- X ++CurrentDevice;
- X return ed;
- X }
- X }
- X cd = FindConfigDev(cd,CurrentDevice->manuf,CurrentDevice->board);
- X }
- X CurrentDevice = (struct ExpDev *)CurrentDevice->node.ln_Succ;
- X return NULL;
- X}
- X
- X/* This function removes a CardROMFile generated I/O ROM table list. */
- X
- Xvoid FreeExpROM(emem)
- Xstruct ExpROMData *emem;
- X{
- X struct ExpROMData *edel;
- X
- X while (emem) {
- X edel = emem;
- X emem = emem->next;
- X FreeMem(edel->imagebase,edel->ROMsize);
- X FreeMem(edel->name,(ULONG)strlen(edel->name)+1);
- X FreeMem(edel,SizeOf(struct ExpROMData));
- X }
- X}
- X
- X/* ====================================================================== */
- X
- X/* This routine is called to configure the system devices without calling any
- X ROM routines that could possibly goober up on older OS releases. Other
- X than skipping ROMs, this should do the same thing as the ConfigChain()
- X function in expansion.library. */
- X
- Xvoid SafeConfigDevs()
- X{
- X struct ConfigDev *cd;
- X char *base = (char *)0xe80000;
- X
- X if (!ExpansionBase) return;
- X
- X /* Should also loop only as long as
- X !(ExpansionBase->eb_Flags & EBB_CLOGGED),
- X but I don't know what EBB_CLOGGED is yet.. */
- X
- X while (cd = AllocConfigDev()) {
- X if (ReadExpansionRom(base,cd)) {
- X FreeConfigDev(cd);
- X break;
- X }
- X
- X /* Got it, let's get rid of any ROM critters. */
- X cd->cd_Rom.er_Type &= ~ERTF_DIAGVALID;
- X
- X /* Now adding the board should be safe! */
- X if (ConfigBoard(base,cd)) {
- X FreeConfigDev(cd);
- X break;
- X }
- X AddConfigDev(cd);
- X }
- X}
- X
- END_OF_FILE
- if test 6166 -ne `wc -c <'expdev.c'`; then
- echo shar: \"'expdev.c'\" unpacked with wrong size!
- fi
- # end of 'expdev.c'
- fi
- if test -f 'idents.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'idents.a'\"
- else
- echo shar: Extracting \"'idents.a'\" \(6346 characters\)
- sed "s/^X//" >'idents.a' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; IDENTS.A MODULE
- X;
- X; This module contains the functions that ID the CPU, MMU, and FPU
- X; type indtalled in the system.
- X;
- X;======================================================================
- X
- X include "setcpu.i"
- X
- X cseg
- X
- X xdef _GetCPUType ; ID the CPU
- X xdef _GetMMUType ; ID the MMU
- X xdef _GetFPUType ; ID the FPU
- X
- X;======================================================================
- X;
- X; This routine checks CPU flags early in ExecBase for extended
- X; CPUs that test as a 68020 under 1.3. If these flags are set,
- X; the actual CPU/MMU type test can be skipped.
- X;
- X;======================================================================
- X
- XTestFlags:
- X moveq.l #0,d0
- X btst.b #AFB_68040,ATNFLGS(a6) ; Does the OS think an '040 is here?
- X beq NoEarly40
- X move.l #68040,d0
- X rts
- XNoEarly40:
- X btst.b #AFB_68030,ATNFLGS(a6) ; Does the OS think an '030 is here?
- X beq NoEarly30
- X move.l #68030,d0 ; Sure does...
- XNoEarly30:
- X rts
- X
- X
- X;======================================================================
- X;
- X; This function returns the type of the CPU in the system as a
- X; longword: 68000, 68010, 68020, or 68030. The testing must be done
- X; in reverse order, in that any higher CPU also has the bits set for
- X; a lower CPU. Also, since 1.3 doesn't recognize the 68030, if I
- X; find the 68020 bit set, I always check for the presence of a
- X; 68030.
- X;
- X; This routine should be the first test routine called under 1.2
- X; and 1.3.
- X;
- X; ULONG GetCPUType();
- X;
- X;======================================================================
- X
- X_GetCPUType:
- X move.l 4,a6 ; Get ExecBase
- X jsr TestFlags ; Check extended CPU types
- X cmp.l #0,d0
- X beq CPURealTest
- X rts
- XCPURealTest:
- X movem.l a4/a5,-(sp) ; Save this register
- X btst.b #AFB_68020,ATNFLGS(a6) ; Maybe a 68020
- X bne FindReal32
- X btst.b #AFB_68010,ATNFLGS(a6) ; Maybe a 68010?
- X bne Found10
- X move.l #68000,d0 ; Just a measley '000
- X movem.l (sp)+,a4/a5
- X rts
- XFound10:
- X move.l #68010,d0 ; Yup, we're an '010
- X movem.l (sp)+,a4/a5
- X rts
- XFindReal32:
- X move.w LIB_VERSION(a6),d0 ; Are we in 2.0?
- X cmp.w #36,d0 ; If so, we don't need to test
- X bge No40
- X
- X lea.l SuperGCT,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X
- X btst.l #CIB_BURST,d0 ; Do we have a set burst bit?
- X beq No30
- X move.l #68030,d0 ; It's a 68030
- X bset.b #AFB_68030,ATNFLGS(a6)
- X movem.l (sp)+,a4/a5
- X rts
- XNo30:
- X btst.l #CIB_ENABLE40,d1 ; Do we have 040 cache enable?
- X beq No40
- X move.l #68040,d0 ; It's a 68040
- X bset.b #AFB_68040,ATNFLGS(a6)
- X movem.l (sp)+,a4/a5
- X rts
- XNo40:
- X move.l #68020,d0 ; Guess we're a plain old '020
- X movem.l (sp)+,a4/a5
- X rts
- X
- X ; This routine tries to set a few interesting CACR bits, and
- X ; returns the actual register value that took in d0.
- XSuperGCT:
- X MOVEC_ cacr,d1 ; Get the cache register
- X move.l d1,d0 ; Make a copy
- X bset.l #CIB_BURST,d0 ; Set the inst burst bit 030
- X bclr.l #CIB_ENABLE,d0 ; Clear the inst cache bit 030
- X bset.l #CIB_ENABLE40,d0 ; Set the inst cache bit 040
- X MOVEC_ d0,cacr ; Try to set the CACR
- X MOVEC_ cacr,d0 ; Save the real value
- X MOVEC_ d1,cacr ; Restore it
- X rte
- X
- X;======================================================================
- X;
- X; This function returns 0L if the system contains no MMU,
- X; 68851L if the system does contain an 68851, or the CPU number
- X; for CPUs with integral CPUs.
- X;
- X; This routine seems to lock up on at least some CSA 68020
- X; boards, though it runs just fine on those from Ronin and
- X; Commodore, as well as all 68030 boards it's been tested on.
- X;
- X; ULONG GetMMUType()
- X;
- X;======================================================================
- X
- X_GetMMUType:
- X move.l 4,a6 ; Get ExecBase
- X jsr TestFlags ; Check extended CPU types
- X cmp.l #0,d0
- X beq MMURealTest
- X rts
- X
- X ; For any other machine, a real test must be done. The test will
- X ; try an MMU instruction. The instruction will fail unless we're
- X ; on a "bogus MMU" system, where the FPU responds as an MMU.
- XMMURealTest:
- X movem.l a3/a4/a5,-(sp) ; Save this stuff
- X move.l #0,a1
- X CALLSYS FindTask ; Call FindTask(0L)
- X move.l d0,a3
- X
- X move.l TC_TRAPCODE(a3),a4 ; Change the exception vector
- X move.l #MMUTraps,TC_TRAPCODE(a3)
- X
- X move.l #-1,d0 ; Try to detect undecode FPU
- X subq.l #4,sp ; Get a local variable
- X PMOVE_ tc,(sp) ; Let's try an MMU instruction
- X addq.l #4,sp ; Return that local
- X move.l a4,TC_TRAPCODE(a3) ; Reset exception stuff
- X movem.l (sp)+,a3/a4/a5 ; and return the registers
- X rts
- X
- X ; This is the exception code. No matter what machine we're on,
- X ; we get an exception. If the MMU's in place, we should get a
- X ; privilige violation; if not, an F-Line emulation exception.
- XMMUTraps:
- X move.l (sp)+,d0 ; Get Amiga supplied exception #
- X cmpi #11,d0 ; Is it an F-Line?
- X beq MMUNope ; If so, go to the fail routine
- X move.l #68851,d0 ; We have MMU
- X addq.l #4,2(sp) ; Skip the MMU instruction
- X rte
- XMMUNope:
- X moveq.l #0,d0 ; It dinna woik,
- X addq.l #4,2(sp) ; Skip the MMU instruction
- X rte
- X
- X;======================================================================
- X;
- X; This function returns the type of the FPU in the system as a
- X; longword: 0 (no FPU), 68881, or 68882.
- X;
- X; ULONG GetFPUType();
- X;
- X;======================================================================
- X
- X_GetFPUType:
- X move.l 4,a6 ; Get ExecBase
- X btst.b #AFB_68040,ATNFLGS(a6) ; Is there a 68040 here?
- X beq Look4FPU
- X move.l #68040,d0
- X rts
- XLook4FPU:
- X move.l a5,-(sp) ; Save this register
- X btst.b #AFB_68881,ATNFLGS(a6) ; Does the OS think an FPU is here?
- X bne FPUHere
- X moveq.l #0,d0 ; No FPU here, dude
- X move.l (sp)+,a5 ; Give back the register
- X rts
- XFPUHere:
- X btst.b #AFB_68882,ATNFLGS(a6) ; How's about an '882?
- X beq FPUTest
- X move.l #68882,d0 ; Sure does...
- X move.l (sp)+,a5
- X rts
- XFPUTest:
- X move.w LIB_VERSION(a6),d0 ; Are we in 2.0?
- X cmp.w #36,d0 ; If so, we don't need to test
- X blt FPUTrap
- X move.l #68881,d0
- X move.l (sp)+,a5
- X rts
- XFPUTrap:
- X lea.l FPUSuper,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X move.l (sp)+,a5 ; Give back registers
- X rts
- XFPUSuper:
- X move.l #68881,d0 ; Assume we're a 68881
- X fsave -(sp) ; Test and check
- X moveq.l #0,d1
- X move.b 1(sp),d1 ; Size of this frame
- X cmpi #$18,d1
- X beq FPU81
- X move.l #68882,d0 ; It's a 68882
- X bset.b #AFB_68882,ATNFLGS(a6)
- XFPU81:
- X frestore (sp)+ ; Restore the stack
- X rte
- X
- X end
- X
- END_OF_FILE
- if test 6346 -ne `wc -c <'idents.a'`; then
- echo shar: \"'idents.a'\" unpacked with wrong size!
- fi
- # end of 'idents.a'
- fi
- if test -f 'makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makefile'\"
- else
- echo shar: Extracting \"'makefile'\" \(464 characters\)
- sed "s/^X//" >'makefile' <<'END_OF_FILE'
- X######################################################################
- X#
- X# Makefile for SetCPU V1.6
- X#
- X######################################################################
- X
- X.a.o:
- X as -o $@ $*.a
- X
- XCFLAGS = +x5
- XLFLAGS = -lm -lc
- X
- XCOBJS = expdev.o memory.o mmu.o coolhand.o misc.o diskio.o setcpu.o
- XAOBJS = idents.o control.o reboot.o other.o
- XOBJS = $(AOBJS) $(COBJS)
- X
- XSetCPU: $(OBJS) setcpu.o
- X ln $(OBJS) -o SetCPU $(LFLAGS)
- X
- X$(COBJS): setcpu.h
- X
- X$(AOBJS): setcpu.i
- END_OF_FILE
- if test 464 -ne `wc -c <'makefile'`; then
- echo shar: \"'makefile'\" unpacked with wrong size!
- fi
- # end of 'makefile'
- fi
- if test -f 'misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc.c'\"
- else
- echo shar: Extracting \"'misc.c'\" \(5481 characters\)
- sed "s/^X//" >'misc.c' <<'END_OF_FILE'
- X/*
- X SetCPU V1.60
- X by Dave Haynie, April 13, 1990
- X Released to the Public Domain
- X
- X MISC.C MODULE
- X
- X This module is responsible for managing ROM image patchs.
- X*/
- X
- X#include "setcpu.h"
- X
- X
- X/* ====================================================================== */
- X
- X/* This replaces the Lattice "stricmp()" function, plus it's a better form
- X for my needs here. */
- X
- XLONG striequ(s1,s2)
- Xchar *s1,*s2;
- X{
- X LONG aok = FALSE;
- X
- X while (*s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
- X return (LONG) (!*s1 && !*s2 && aok);
- X}
- X
- XLONG strniequ(s1,s2,n)
- Xchar *s1,*s2;
- Xunsigned n;
- X{
- X LONG aok = FALSE;
- X
- X while (n-- && *s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
- X return aok;
- X}
- X
- X/* ====================================================================== */
- X
- X/* The device I/O functions. */
- X
- X/* This routine turns off the motor. */
- X
- Xvoid MotorOff(req)
- Xstruct IOStdReq *req;
- X{
- X req->io_Length = 0L;
- X req->io_Command = TD_MOTOR;
- X (void)DoIO((struct IORequest *)req);
- X}
- X
- X/* This function fills the buffer "buf" with the contents of the given
- X sector number. Returns 0 if there's no error. */
- X
- XBYTE ReadBuf(buf,sect,req)
- Xchar *buf;
- XLONG sect;
- Xstruct IOStdReq *req;
- X{
- X req->io_Length = 512L;
- X req->io_Data = (APTR) buf;
- X req->io_Command = CMD_READ;
- X req->io_Offset = (512L * sect);
- X (void)DoIO((struct IORequest *)req);
- X return req->io_Error;
- X}
- X
- X/* This function takes in a DOS name, and returns either the
- X trackdisk.device unit that it corresponds to, or -1L. */
- X
- XLONG CheckTDDev(name)
- Xchar *name;
- X{
- X char *devname;
- X struct DosLibrary *dl;
- X struct RootNode *dr;
- X struct DosInfo *di;
- X struct DeviceNode *dev;
- X struct FileSysStartupMsg *start;
- X struct DosEnvec *env;
- X
- X dl = (struct DosLibrary *)OpenLibrary("dos.library",0L);
- X dr = (struct RootNode *)dl->dl_Root;
- X di = (struct DosInfo *)BADDR(dr->rn_Info);
- X dev = (struct DeviceNode *)BADDR(di->di_DevInfo);
- X CloseLibrary((struct Library *)dl);
- X
- X /* Next we find the device */
- X if (name[strlen(name)-1] == ':') name[strlen(name)-1] = '\0';
- X
- X for (; dev != NULL; dev = (struct DeviceNode *)BADDR(dev->dn_Next)) {
- X if (dev->dn_Type != DLT_DEVICE) continue;
- X devname = (char *)BADDR(dev->dn_Name);
- X if (strniequ(name,devname+1,(unsigned)devname[0])) break;
- X }
- X
- X /* Is it a valid trackdisk.device? */
- X if (!dev) return -1L;
- X if (!(start = (struct FileSysStartupMsg *)BADDR(dev->dn_Startup))) return -1L;
- X env = (struct DosEnvec *)BADDR(start->fssm_Environ);
- X if (env->de_BlocksPerTrack != 11L || env->de_LowCyl != 0L) return -1L;
- X devname = (char *)BADDR(start->fssm_Device);
- X if (!strniequ(devname+1,"trackdisk.device",16)) return -1L;
- X
- X return start->fssm_Unit;
- X}
- X
- X/* ====================================================================== */
- X
- X/* The patch manager stuff. */
- X
- X/* The "JSR address" opcode used for my patches. */
- X
- X#define JSR_OPCODE 0x4eb9
- X
- X/* These are for some string patches */
- X
- Xstatic char DiskS[] = "SALV to recover it! ";
- X
- X/* These are the V1.3 patches */
- X
- Xstruct pitem PL_345[] = {
- X { PT_KEYBOARD,0,0x2528a, 0L, NULL }, /* Keyboard... */
- X { PT_STRING, 0,0x3fe19, 20L, (UWORD *)DiskS }, /* "DiskDoctor" name */
- X { PT_END, 0, 0, 0L, NULL }
- X};
- X
- Xstruct pitem PL_33180[] = {
- X { PT_KEYBOARD,0,0x2572a, 0L, NULL }, /* Keyboard... */
- X { PT_STRING, 0,0x3fe11, 20L, (UWORD *)DiskS }, /* "DiskDoctor" name */
- X { PT_END, 0, 0, 0L, NULL }
- X};
- X
- X/* This is main system patch list. */
- X
- Xstruct patch SystemPatch[] = {
- X { &SystemPatch[1], &PL_345[0],34,5 },
- X { NULL, &PL_33180[0],33,180 }
- X};
- X
- X/* This is a pointer to the base of the last applied patch, for making
- X patch links. The structure of any applied allocated patch, such as
- X a JSR patch, is a link pointer, the actual patch size, and then the
- X patch code. This lets any version of SetCPU remove allocated patches
- X from any other version, providing it can locate the tag. */
- X
- Xstruct MemChunk *lastpatch = NULL;
- X
- X/* This routine applys the patch */
- X
- XLONG AddPatch(rom,lst,tag)
- XULONG rom;
- Xstruct patch *lst;
- Xstruct systag *tag;
- X{
- X UWORD *kickver = (UWORD *)(0x100000C - ( * (ULONG *) 0xFFFFEC ));
- X UWORD *addr, *base;
- X struct pitem *item;
- X struct MemChunk *chunk;
- X LONG any = FALSE;
- X
- X while (lst) {
- X if (lst->Version == kickver[0] && lst->Revision == kickver[1]) {
- X for (item = &lst->list[0]; item->Type != PT_END; ++item) {
- X any = TRUE;
- X switch (item->Type) {
- X case PT_IGNORE :
- X break;
- X case PT_STRING :
- X MemCopy(item->Code,(char *)(rom+item->Offset),item->Length);
- X ++tag->patches;
- X break;
- X case PT_JSR :
- X chunk = (struct MemChunk *)AllocMem(item->Length+14L,0L);
- X chunk->mc_Next = lastpatch;
- X lastpatch = chunk;
- X chunk->mc_Bytes = item->Length+14L;
- X addr = (UWORD *)(((ULONG)chunk)+8L);
- X base = (UWORD *)(rom+item->Offset);
- X MemCopy(base,addr,6L);
- X base[0] = (UWORD)JSR_OPCODE;
- X base[1] = (UWORD)(((ULONG)addr)>>16L);
- X base[2] = (UWORD)(((ULONG)addr)&0x0ffff);
- X MemCopy(item->Code,&addr[3],item->Length);
- X ++tag->patches;
- X break;
- X }
- X }
- X }
- X lst = lst->next;
- X }
- X return any;
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- END_OF_FILE
- if test 5481 -ne `wc -c <'misc.c'`; then
- echo shar: \"'misc.c'\" unpacked with wrong size!
- fi
- # end of 'misc.c'
- fi
- if test -f 'other.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'other.a'\"
- else
- echo shar: Extracting \"'other.a'\" \(4879 characters\)
- sed "s/^X//" >'other.a' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; OTHER.A MODULE
- X;
- X; This module contains miscellaneous assembly functions that just
- X; didn't seem to fit in elsewhere.
- X;
- X;======================================================================
- X
- X include "setcpu.i"
- X
- X cseg
- X
- X;**********************************************************************
- X;
- X; Some useful MMU functions.
- X;
- X**********************************************************************
- X
- X xdef _SetMMUTag ; Sets up MMU from systag
- X xdef _FlushATC ; Flush MMU address translation cache
- X
- X;======================================================================
- X;
- X; This function cleanly sets up a new MMU context. It accepts a
- X; valid systag, and will first go to Supervisor more, turn off
- X; the current MMU setup, then set CRP and finally TC. The reason
- X; this call is needed is that we need the OS alive to get to
- X; Supervisor mode. Setting up a new MMU context would normally
- X; take three calls to Supervisor(), one to turn off the MMU
- X; (ROM dies...), two to set first the new CRP and then the new
- X; TC.
- X;
- X; void SetMMUTag(struct systag *tag)
- X;
- X;======================================================================
- X
- X_SetMMUTag:
- X move.l 4(sp),a0 ; Get the systag where we can use it
- X move.l 4,a6 ; Get ExecBase
- X movem.l a2/a5,-(sp)
- X move.l a0,a2
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X movem.l (sp)+,a2/a5 ; Give back registers
- X rts
- X1$
- X lea.l TAG_TC(a2),a0 ; Get TC register
- X lea.l TAG_CRP_0(a2),a1 ; Get CRP register
- X
- X and.l #$7fffffff,(a0) ; Turn off MMU
- X PMOVE_ (a0),tc
- X or.l #$80000000,(a0)
- X PMOVE_ (a1),crp ; Load up the CRP value
- X PMOVE_ (a0),tc ; MMU goes back on
- X rte
- X
- X;======================================================================
- X;
- X; This function flushes the MMU Address Translation Cache.
- X;
- X; void FlushATC(void)
- X;
- X;======================================================================
- X
- X_FlushATC:
- X move.l 4,a6 ; Get ExecBase
- X move.l a5,-(sp)
- X lea.l 1$,a5 ; Get the start of the supervisor code
- X CALLSYS Supervisor
- X movem.l (sp)+,a5 ; Give back registers
- X rts
- X1$
- X PFLUSHA_ ; Flush the ATC
- X rte
- X
- X;**********************************************************************
- X;
- X; This section contains the keyboad patch routine.
- X;
- X;**********************************************************************
- X
- X xdef _KeyCode ; Start of the keyboard patch
- X xdef _KeyCodeSize ; Size of the keyboard patch
- X xdef _SetKeyDelay ; Set keyboard count parameter
- X
- X;======================================================================
- X;
- X; This is the keyboard delay patch routine.
- X;
- X;======================================================================
- X
- XKeyCode:
- X movem.l d0/d1,-(sp)
- XKeyOpt:
- X move.l #12345678,d0
- X1$ move.w ANYCREG,d1
- X subq.l #1,d0
- X bne 1$
- X movem.l (sp)+,d0/d1
- X rts
- XKeyCodeEnd:
- X
- X;======================================================================
- X;
- X; This function programs the patch delay value.
- X;
- X; void SetKeyDelay(ULONG)
- X;
- X;======================================================================
- X
- X_SetKeyDelay:
- X move.l 4(sp),d0 ; Get the delay value
- X lea KeyOpt,a0 ; Get the location
- X move.l d0,2(a0) ; Set the value
- X rts
- X
- X_KeyCode:
- X dc.l KeyCode
- X_KeyCodeSize:
- X dc.l KeyCodeEnd-KeyCode+1
- X
- X;**********************************************************************
- X;
- X; This section contains the items used for the exception handler.
- X;
- X;**********************************************************************
- X
- X xdef _BerrCode ; Start of the trap routine
- X xdef _BerrCodeSize ; Size of the trap routine
- X
- X;======================================================================
- X;
- X; This is the exception handler for Bus Errors (level 2). User
- X; code that misbehaves when the MMU is on can result in such an
- X; exception. While the code needs to be fixed if this happens,
- X; it's very possible that the code is not depending on it's random
- X; action; especially in the case of an accidental write to ROM
- X; space, which is harmless on a normally configured machine.
- X; This routine is never directly called by SetCPU. Instead, it's
- X; copied into memory that's allocated as permanent by SetCPU.
- X;
- X;======================================================================
- X
- XSTATUS EQU $0a+4
- X
- XSR_DF EQU 8
- X
- XBerrTrapCode:
- X move.l d0,-(sp) ; Save d0...
- X move.w STATUS(sp),d0 ; Fetch exception status register
- X
- X bclr.l #SR_DF,d0 ; Clear the data fault bit
- Xrepair:
- X move.w d0,STATUS(sp) ; Fix the status word
- Xdone:
- X move.l (sp)+,d0
- X rte
- X
- XBerrTrapEnd:
- X
- X;======================================================================
- X;
- X; These give us the size and location of the Bus Error Code.
- X;
- X;======================================================================
- X
- X_BerrCode:
- X dc.l BerrTrapCode
- X_BerrCodeSize:
- X dc.l BerrTrapEnd-BerrTrapCode+1
- X
- X end
- END_OF_FILE
- if test 4879 -ne `wc -c <'other.a'`; then
- echo shar: \"'other.a'\" unpacked with wrong size!
- fi
- # end of 'other.a'
- fi
- if test -f 'reboot.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'reboot.a'\"
- else
- echo shar: Extracting \"'reboot.a'\" \(5211 characters\)
- sed "s/^X//" >'reboot.a' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; REBOOT.A MODULE
- X;
- X; This module contains functions that do the clever reset magic
- X; needed for KickStart imaging.
- X;
- X;======================================================================
- X
- X include "setcpu.i"
- X
- X cseg
- X
- X xdef _RAMBoot ; Effects the reboot into a RAM image
- X xdef _BootCode ; Actual main reboot code
- X xdef _BootCodeSize ; Size of this magic code
- X xdef _CleanBoot ; Boot back to system ROM, reset Exec
- X xdef _ResetCode ; Smart reset routine
- X xdef _ResetCodeSize ; Size of this magic code
- X
- X;======================================================================
- X;
- X; This is the RAMBoot routine as called from C. The C code has
- X; set up the tag structure with valid MMU data and a pointer to
- X; the main reset routine in safe memory. The routine will fetch
- X; the systag from the stack, then call the safe routine in the
- X; supervisor mode. That call is the last kernal call used; the
- X; reset routine itself doesn't use any ROM routines, so it can
- X; safely turn off the MMU before it goes to work, methinks.
- X;
- X; void RAMBoot(struct systag *tag, LONG ClearExec,LONG Delay)
- X;
- X;======================================================================
- X
- X_RAMBoot:
- X move.l 4(sp),a2 ; Get the systag where we can use it
- X move.l 8(sp),d4 ; KeepExec?
- X move.l 12(sp),d5 ; Delay value
- X move.l 4,a6
- X lea.l TrickyBits,a5 ; Get the supervisor code
- X CALLSYS Supervisor ; Go to supervisor mode
- X rts ; We never get here!
- X
- X;======================================================================
- X;
- X; This is the start of the supervisor portion of the reboot code.
- X; This code gets things in the registers the ChipRAM code
- X; requires, loads up a reset routine into cache, freezes the
- X; cache, resets, waits for the CIA chips, and then calls the
- X; ChipRAM code portion which will turn the MMU on and jump to
- X; ROM's start address.
- X;
- X; a2 SetCPU system tag
- X; a6 ExecBase
- X; d4 KeepExec Flag
- X; d5 Boot Delay
- X;
- X;======================================================================
- X
- XTrickyBits:
- X move.l TAG_ROMSTART(a2),a4 ; Get the ROM jump address
- X move.l TAG_RESETCODE(a2),a3 ; Get the ChipRAM based code
- X lea.l TAG_CRP_0(a2),a1 ; Get CRP register
- X lea.l TAG_TC(a2),a0 ; Get TC register
- X
- X and.l #$7fffffff,(a0) ; Turn off MMU
- X PMOVE_ (a0),tc ; -> $f010,$4000
- X or.l #$80000000,(a0) ; Prep for startup
- X PMOVE_ (a1),crp ; -> $f011,$4c00
- X
- X cmp.l #0,d4 ; If asked for, zap ExecBase good
- X bne 1$
- X moveq.l #0,d0
- X move.l d0,$4
- X1$
- X move.l #1,d1 ; Make sure inst cache is on!
- X MOVEC_ d1,cacr
- X
- X move.l #1,d3 ; First pass, no delay
- X lea.l CacheRun,a6 ; Get the initial branch address
- X
- XRSTLoop:
- X jmp (a6)
- X
- XRSTIt:
- X reset ; Clobber the system
- X reset
- X
- XCacheRun:
- X move.w ANYCREG,d1 ; Set a spell, take yer shoes off
- X subq.l #1,d3
- X bne CacheRun
- X move.b #3,$bfe201 ; Turn off Amiga ROM Overlay
- X move.b #2,$bfe001
- X
- X cmp.l a3,a6 ; Last time through?
- X beq RSTLoop ; If so, go back
- X
- X move.l a3,a6 ; No? Get the address,
- X move.l d5,d3 ; the delay
- X move.l #3,d1 ; freeze the cache
- X MOVEC_ d1,cacr
- X bra RSTIt ; And Up to the reset stuff
- X
- X;======================================================================
- X;
- X; This is the RAM reboot code, which is called to reset the
- X; system into the new ROM, which is of course now in some magic
- X; and safe place. The ROM's jump address in in A4 when this
- X; code is called, and the TC register is in A0.
- X;
- X;======================================================================
- X
- XRAMBootCode:
- X move.l #0,d1 ; Turn all caches off
- X MOVEC_ d1,cacr
- X move.l #10,d1 ; Let 'em know we're here
- X1$
- X bchg #1,$bfe001
- X move.l #80000,d0
- X2$ subq.l #1,d0
- X bne 2$
- X dbra d1,1$
- X
- X PMOVE_ (a0),tc ; Turn on the MMU
- X jmp (a4) ; Start up the ROM
- X nop
- X nop
- X nop
- X nop
- XRAMBootEnd:
- X
- X_BootCode:
- X dc.l RAMBootCode
- X_BootCodeSize:
- X dc.l RAMBootEnd-RAMBootCode+1
- X
- X;======================================================================
- X;
- X; This routine forces a boot back to ROM, clearing out the
- X; ExecBase and turning off the MMU and caches.
- X;
- X; void CleanBoot(void)
- X;
- X;======================================================================
- X
- X_CleanBoot:
- X move.l 4,a6
- X
- X lea 1$,a5
- X CALLSYS Supervisor
- X rts
- X1$
- X move.l #0,(sp) ; Turn off MMU
- X move.l sp,a0
- X PMOVE_ (a0),tc ; -> $f010,$4000
- X
- X move.l #0,d1 ; Turn all caches off
- X MOVEC_ d1,cacr
- X
- X move.l 4,a6 ; Clear out ExecBase
- X move.l #0,$4
- X
- X move.l $00f80000,d0 ; Which kind of real ROM?
- X cmp.l #$11144ef9,d0
- X beq 2$
- X move.l $00fc0004,a0
- X bra 3$
- X2$
- X move.l $00f80004,a0 ; We have a 512K ROM
- X3$
- X reset
- X reset
- X jmp (a0)
- X nop
- X nop
- X nop
- X nop
- XCleanBootEnd:
- X
- X;======================================================================
- X;
- X; Pointers to the smart reset routine, and the length of this
- X; routine. Currently I'm using the CleanBoot routine, which will
- X; get the machine back to the ROM OS. A better smart reset routine
- X; could boot back to the virtual ROM rather than the physcial ROM.
- X;
- X;======================================================================
- X
- X_ResetCode:
- X dc.l _CleanBoot
- X_ResetCodeSize:
- X dc.l CleanBootEnd-_CleanBoot+1
- X
- X end
- END_OF_FILE
- if test 5211 -ne `wc -c <'reboot.a'`; then
- echo shar: \"'reboot.a'\" unpacked with wrong size!
- fi
- # end of 'reboot.a'
- fi
- if test -f 'setcpu.i' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'setcpu.i'\"
- else
- echo shar: Extracting \"'setcpu.i'\" \(4271 characters\)
- sed "s/^X//" >'setcpu.i' <<'END_OF_FILE'
- X;======================================================================
- X;
- X; SetCPU V1.60
- X; by Dave Haynie, April 13, 1990
- X; Released to the Public Domain
- X;
- X; Assembly Header File
- X;
- X; All assembly files need this included
- X;
- X;======================================================================
- X
- X;======================================================================
- X;
- X; Macros & constants used herein. The Manx assembler is supposed
- X; to handle the 68881 and some of the 68020/30 instructions, but
- X; these macros will help out on older assemblers, and complete the
- X; set of instructions I need.
- X;
- X;======================================================================
- X
- XCALLSYS macro *
- X jsr LVO\1(A6)
- X endm
- X
- XPMOVE_ macro *
- X ifc '\1','tc'
- X ifc '\2','(sp)'
- X dc.w $f017 ; PMOVE tc,(sp)
- X dc.w $4200
- X mexit
- X endc
- X ifc '\2','(a0)'
- X dc.w $f010 ; PMOVE tc,(a0)
- X dc.w $4200
- X mexit
- X endc
- X endc
- X ifc '\1','crp'
- X ifc '\2','(a0)'
- X dc.w $f010 ; PMOVE crp,(a0)
- X dc.w $4e00
- X mexit
- X endc
- X endc
- X ifc '\1','(a0)'
- X ifc '\2','crp'
- X dc.w $f010 ; PMOVE (a0),crp
- X dc.w $4c00
- X mexit
- X endc
- X ifc '\2','tc'
- X dc.w $f010 ; PMOVE (a0),tc
- X dc.w $4000
- X mexit
- X endc
- X endc
- X ifc '\1','(a1)'
- X ifc '\2','crp'
- X dc.w $f011 ; PMOVE (a1),crp
- X dc.w $4c00
- X mexit
- X endc
- X endc
- X endm
- XPFLUSHA_ macro *
- X dc.w $f000
- X dc.w $2400
- X endm
- X
- XMOVEC_ macro *
- X ifc '\1','cacr'
- X ifc '\2','d0'
- X dc.w $4e7a ; MOVEC cacr,d0
- X dc.w $0002
- X mexit
- X endc
- X ifc '\2','d1'
- X dc.w $4e7a ; MOVEC cacr,d1
- X dc.w $1002
- X mexit
- X endc
- X endc
- X ifc '\2','cacr'
- X ifc '\1','d0'
- X dc.w $4e7b ; MOVEC d0,cacr
- X dc.w $0002
- X mexit
- X endc
- X ifc '\1','d1'
- X dc.w $4e7b ; MOVEC d1,cacr
- X dc.w $1002
- X mexit
- X endc
- X endc
- X ifc '\1','vbr'
- X ifc '\2','d0'
- X dc.w $4e7a ; MOVEC vbr,d0
- X dc.w $0801
- X mexit
- X endc
- X endm
- X
- XCIB_ENABLE EQU 0
- XCIB_FREEZE EQU 1
- XCIB_ENTRY EQU 2
- XCIB_CLEAR EQU 3
- XCIB_BURST EQU 4
- X
- XCDB_ENABLE EQU 8
- XCDB_FREEZE EQU 9
- XCDB_ENTRY EQU 10
- XCDB_CLEAR EQU 11
- XCDB_BURST EQU 12
- XCDB_WALLOC EQU 13
- X
- XCIB_ENABLE40 EQU 15
- XCDB_ENABLE40 EQU 31
- X
- XAFB_68030 EQU 2
- XAFB_68040 EQU 3
- XAFB_68882 EQU 5
- X
- XATNFLGS EQU $129
- X
- XLVOSupervisor EQU -30
- XLVOSuperState EQU -150
- XLVOFindTask EQU -294
- XLVOAllocTrap EQU -342
- XLVOFreeTrap EQU -348
- XLVOCacheClearU EQU -636
- XLVOCacheControl EQU -648
- X
- XANYCREG EQU $00dff010
- X
- X;======================================================================
- X;
- X; Need just a little more stuff
- X;
- X;======================================================================
- X
- X NOLIST
- X include "exec/types.i"
- X include "exec/execbase.i"
- X include "exec/tasks.i"
- X LIST
- X
- X;======================================================================
- X;
- X; The assembly version of my tag structure
- X;
- X;======================================================================
- X
- X STRUCTURE TAG,0
- X ULONG TAG_TAGSIZE ; Size of this tag
- X ULONG TAG_PROGVER ; The program version
- X APTR TAG_MAINTABLE ; The main ROM table
- X APTR TAG_ROMHI ; The main ROM image
- X UWORD TAG_ROMTYPE ; Type of MMU ROM
- X UWORD TAG_PATCHES ; The number of other patches applied
- X APTR TAG_PATCHLIST ; List of installed patches
- X APTR TAG_DEVS ; Translated device ROMs
- X ULONG TAG_TC ; Precomputed TC used for KICK.
- X ULONG TAG_CRP_0 ; Precomputed CRP used for KICK.
- X ULONG TAG_CRP_1
- X UWORD TAG_CONFIG ; Configuration status.
- X ULONG TAG_BERRSIZE ; Size of bus error handler.
- X APTR TAG_OLDBERR ; The old BERR routine.
- X APTR TAG_BERRHANDLER ; My BERR routine.
- X SHORT TAG_WRAPUP ; Upper address wrap bound.
- X SHORT TAG_WRAPDOWN ; Lower address wrap bound.
- X ULONG TAG_TABLESIZE ; Main table size.
- X APTR TAG_RESETCODE ; Actual reset routine
- X ULONG TAG_ROMSIZE ; Size of ROM image
- X ULONG TAG_ROMLOC ; Where does the fool thing go?
- X ULONG TAG_ROMSTART ; And where do we start it up?
- X APTR TAG_ROMLO ; Secondary ROM image, if needed
- X APTR TAG_SYSSTACK ; Physical system stack image
- X ULONG TAG_SYSSTKSIZE ; System Stack allocated size
- X ULONG TAG_RESETSIZE ; Size of the reset code.
- X APTR TAG_OLDRESET ; Old Reset Code
- X LABEL TAG_SIZE
- X
- X;TAG_TC EQU 28
- X;TAG_CRP_0 EQU 32
- X;TAG_RESETCODE EQU 62
- X;TAG_ROMSTART EQU 74
- X
- X machine mc68020
- X mc68881
- X
- END_OF_FILE
- if test 4271 -ne `wc -c <'setcpu.i'`; then
- echo shar: \"'setcpu.i'\" unpacked with wrong size!
- fi
- # end of 'setcpu.i'
- fi
- echo shar: End of archive 1 \(of 4\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-